/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.fop.apps.Driver;
import org.apache.fop.apps.FOPException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 *
 * @author ThanhTai
 */
public class SupportUtil {

    public SupportUtil() {
    }

    public void marshal(String filePath, Object obj) {
        try {
            File file = new File(filePath);
            file.delete();
            JAXBContext ctx = JAXBContext.newInstance(obj.getClass());
            Marshaller mar = ctx.createMarshaller();
            mar.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
            mar.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            File f = new File(filePath);
            mar.marshal(obj, f);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    public Object unmarshal(String packagePath, String filePath) {
        try {
            JAXBContext jc = JAXBContext.newInstance(packagePath);
            Unmarshaller u = jc.createUnmarshaller();
            File f = new File(filePath);
            Object item = (Object) u.unmarshal(f);
            return item;
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Object unmarshalFromString(String packagePath, String xmlDoc) {
        try {
            String context = xmlDoc;
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(new InputSource(new StringReader(context)));
            Source src = new DOMSource(doc);

            JAXBContext jc = JAXBContext.newInstance(packagePath);
            Unmarshaller u = jc.createUnmarshaller();
            //File f = new File(xmlDoc);
            Object item = (Object) u.unmarshal(src);
            return item;
        } catch (SAXException ex) {
            Logger.getLogger(SupportUtil.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(SupportUtil.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(SupportUtil.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void marshalToOutputStream(Object object, OutputStream os) {
        try {
            JAXBContext contex = JAXBContext.newInstance(object.getClass());
            Marshaller marshaller = contex.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            marshaller.marshal(object, os);
        } catch (JAXBException ex) {
            ex.printStackTrace();
        }
    }

    public String marshalReturnString(Object object) {
        //File xmlFile = new File(path);
        StringWriter xmlString = new StringWriter();
        try {
            JAXBContext contex = JAXBContext.newInstance(object.getClass());
            Marshaller marshaller = contex.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            marshaller.marshal(object, xmlString);
        } catch (JAXBException ex) {
            ex.printStackTrace();
        }
        return xmlString.toString();
    }

    public Object unMarshalFromInputStream(String packagePath, InputStream xmlFile) {
        Object result = null;
        try {
            JAXBContext ctx = JAXBContext.newInstance(packagePath);
            Unmarshaller unmarshaller = ctx.createUnmarshaller();
            result = unmarshaller.unmarshal(xmlFile);
        } catch (JAXBException ex) {
            ex.printStackTrace();
        }
        return result;
    }

    public void transform(String xmlURL, String xslURL,
            String htmlURL, List<Map<String, String>> params) {
        try {
            TransformerFactory tff = TransformerFactory.newInstance();
            StreamSource xmlFile = new StreamSource(xmlURL);
            StreamSource xslFile = new StreamSource(xslURL);
            Transformer tf = tff.newTransformer(xslFile);
            StreamResult htmlFile = new StreamResult(
                    new FileOutputStream(htmlURL));
            for (int i = 0; i < params.size(); i++) {
                String name = params.get(i).get("NAME");
                String value = params.get(i).get("VALUE");
                tf.setParameter(name, value);
            }
            tf.transform(xmlFile, htmlFile);
        } catch (TransformerException ex) {
            ex.printStackTrace();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
    }

    public void exportPDF(String foURL, String pdfURL) {
        InputStream input = null;
        try {
            Driver driver = new Driver();
            ConsoleLogger logger = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);
            driver.setLogger(logger);
            org.apache.fop.messaging.MessageHandler.setScreenLogger(logger);
            driver.setRenderer(Driver.RENDER_PDF);
            File xslFOFile = new File(foURL);
            File pdfFile = new File(pdfURL);
            input = new FileInputStream(xslFOFile);
            driver.setInputSource(new InputSource(input));
            OutputStream output = new FileOutputStream(pdfFile);
            driver.setOutputStream(output);
            driver.run();
            output.flush();
            output.close();
        } catch (FOPException ex) {
            Logger.getLogger(SupportUtil.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(SupportUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public XMLGregorianCalendar convertUtilDateToXMLGregorianCalendar(java.util.Date inputDate) {
        try {
            GregorianCalendar gc = new GregorianCalendar();
            gc.setTimeInMillis(inputDate.getTime());
            XMLGregorianCalendar abc = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
            return abc;
        } catch (DatatypeConfigurationException ex) {
            Logger.getLogger(SupportUtil.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public java.util.Date convertXMLGregorianCalendarToUtilDate(XMLGregorianCalendar inputDate) {
        try {
            java.util.Date abc = inputDate.toGregorianCalendar().getTime();
            return abc;
        } catch (Exception ex) {
            Logger.getLogger(SupportUtil.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }
}
